package cn.jhz.learn.community_dynamic.wbms.controller.api;

import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import cn.jhz.learn.community_dynamic.common.bean.JsonData;
import cn.jhz.learn.community_dynamic.common.exception.RequestException;
import cn.jhz.learn.community_dynamic.common.util.VerifyHelper;
import cn.jhz.learn.community_dynamic.dao.PermissionJpaRepository;
import cn.jhz.learn.community_dynamic.dao.RoleJpaRepository;
import cn.jhz.learn.community_dynamic.dao.UserJpaRepository;
import cn.jhz.learn.community_dynamic.manager.RoleManager;
import cn.jhz.learn.community_dynamic.model.RoleEntity;
import cn.jhz.learn.community_dynamic.security.validation.RegexpRules;
import cn.jhz.learn.community_dynamic.vo.wbms.RoleView;

@RestController
@RequestMapping("api/")
public class RoleController {
    private final RoleJpaRepository roleJpaRepository;
    private final UserJpaRepository userJpaRepository;
    private final PermissionJpaRepository permissionJpaRepository;
    private final RoleManager roleManager;

    @Autowired
    public RoleController(RoleJpaRepository roleJpaRepository, UserJpaRepository userJpaRepository, PermissionJpaRepository permissionJpaRepository, RoleManager roleManager) {
	super();
	this.roleJpaRepository = roleJpaRepository;
	this.userJpaRepository = userJpaRepository;
	this.permissionJpaRepository = permissionJpaRepository;
	this.roleManager = roleManager;
    }
    
    @GetMapping("auth/role/list")
    @PreAuthorize("hasAuthority('role::get_list')")
    public JsonData getList() {
	return JsonData.newSuccessInstance(this.roleJpaRepository.findAll().parallelStream().map(RoleView.adpt).collect(Collectors.toList()));
    }
    
    @PostMapping("auth/role/add")
    @PreAuthorize("hasAuthority('role::add')")
    public JsonData add(@Validated @RequestBody RoleView role) {
	
	VerifyHelper.verify(role, (columnType)->{
	    switch (columnType) {
	    case NAME:
		if(this.roleJpaRepository.existsByname(role.getName())) {
		    
		    throw new RequestException("角色名已被使用!");
		}
		break;
	    case PERMISSIONS:
		if(role.getPermissions().size() > 0) {
		    if(this.permissionJpaRepository.countByIdIn(role.getPermissions()) != role.getPermissions().size()) {
			
			throw new RequestException("存在无效权限码!");
		    }
		}
		break;
	    case STATUS:
		break;
	    default:
		VerifyHelper.defaultAction.accept(columnType);
	    }  
	});
	
	return JsonData.newSuccessInstance(RoleView.adpt.apply(this.roleManager.addInstance(this.roleManager.newInstance(role))));
    }
    
    @PatchMapping("auth/role/info")
    @PreAuthorize("hasAuthority('role::patch_info')")
    public JsonData patch(@Validated(RegexpRules.Patch.class) @RequestBody RoleView role) {
	VerifyHelper.verify(role, (columnType) -> {
	    switch (columnType) {
	    case ID:
		if (!this.roleJpaRepository.existsById(role.getId())) {

		    throw new RequestException("角色不存在!");
		}
		break;
	    case NAME:
		if(StringUtils.isNotBlank(role.getName())) {
		    if (this.roleJpaRepository.existsByname(role.getName())) {
			new RequestException("角色名已被使用!");
		    }
		}else {
		    throw new RequestException("无效角色名!");
		}
		
		break;
	    case PERMISSIONS:
		if (role.getPermissions().size() > 0) {
		    if (this.permissionJpaRepository.countByIdIn(role.getPermissions()) != role.getPermissions().size()) {
			throw new RequestException("存在无效权限码!");
		    }
		}
		break;
	    case STATUS:
		break;
	    default:
		VerifyHelper.defaultAction.accept(columnType);
	    }
	});
	return JsonData.newSuccessInstance(RoleView.adpt.apply(this.roleManager.updateByRole(role)));
    }
    
    @DeleteMapping("auth/role/delete/{id}")
    @PreAuthorize("hasAuthority('role::delete')")
    public JsonData delete(@PathVariable("id") Integer id) {
	// TODO 添加手动删除关联关系
	// TODO 添加权限检查
	Optional<RoleEntity> temp = this.roleJpaRepository.findById(id);
	if(temp.isPresent()) {
	    if(this.userJpaRepository.countByRoles_id(id) > 0) {
		throw new RequestException("仍有用户被关联，无法删除!");
	    }
	}else {
	    // TODO 抛异常
	    throw new RequestException("无效角色!");
	}
	this.roleManager.clearRelation(temp.get());
	this.roleManager.delete(id);
	return JsonData.newSuccessInstance();
    }
}
